import json

from odoo import models
import yaml
from odoo import api
import threading
from ...functions.marketing_coupon_func import MarketingCouponFunc
from odoo.addons.rp_marketing_management.functions.marketing_schedule_func import SCHEDULE_TYPE
from odoo.modules.module import get_module_path
from ..inherit.rp_register_mock_tran_inherit_for_marketing import RpRegisterMockTranInheritForMarketing
from ..tools.rp_prefix_generator_fc import RpPrefixGeneratorFc


class RpMarketingApplicationHook(models.AbstractModel):
    """
    抽象模型用于初始化数据
    """
    _name = 'rp.marketing.application.hook'

    def _register_hook(self):
        """
        应用初始化
        """
        # 初始化邀请数据
        self.init_invite_category()
        # 开启线程监听队列
        # self.create_daemon_thread()

    def init_invite_category(self):
        # 读取配置文件数据
        module_path = get_module_path('rp_marketing_management')
        with open(f'{module_path}/config/init_data_config.yaml', 'r', encoding='utf-8') as f:
            config_data = yaml.safe_load(f)
        for record in config_data.get('InitData').get('InviteCategory'):
            # 初始化邀请任务数据
            category_id = self.env['rp.invite.category'].search([('name', '=', record)])
            if len(category_id.ids) == 0:
                values = {
                    'name': record,
                    'invite_code_prefix': RpPrefixGeneratorFc(self.env).get_code(record)
                }
                # 创建记录
                self.env['rp.invite.category'].create([values])

    def create_daemon_thread(self):
        # 并发的线程数为10
        max_connections = 10
        pool_sema = threading.BoundedSemaphore(max_connections)  # 信号量控制线程并发数
        # 线程加锁
        pool_sema.acquire()
        # pool_sema 控制线程数的个数
        m = threading.Thread(target=self.sub_func_ytc, args=(pool_sema,))
        # 设置为守护线程
        m.daemon = True
        m.start()

    """
    -----------------------------------------------------------------------------
    监听处理函数
    """

    def sub_func_ytc(self, pool_sema):
        try:
            while True:
                with api.Environment.manage():
                    # 新线程需要开启新的游标
                    new_cr = self.pool.cursor()
                    self = self.with_env(self.env(cr=new_cr))
                    # 获取数据
                    payload = RpRegisterMockTranInheritForMarketing.q.get()
                    obj_data = json.loads(payload)
                    res_person = obj_data.get('id')
                    invite_code = obj_data.get('invite_code')
                    res_person = self.env['rp.customer'].search([('id', '=', res_person)])
                    schedule_id = self.env['rp.marketing.auto.schedule'].search([('schedule_type', '=', SCHEDULE_TYPE[1][0]), ('schedule_state', '=', 'done')])
                    # 返现
                    if schedule_id.cash_back_tag:
                        price = res_person.remaining_sum + schedule_id.cash_back_price
                        res_person.write({'remaining_sum': price})
                    # 返优惠券
                    if schedule_id.coupon_issue_tag:
                        coupon_lines = schedule_id.coupon_line_display_ids
                        for coupon_line in coupon_lines:
                            for i in range(coupon_line.amount):
                                MarketingCouponFunc(self.env).issue_coupon_to_customer(coupon_line.rp_coupon_template_id, res_person)
                    self.env.cr.commit()
                    new_cr.close()
                    new_cr._cnx.close()
        except Exception:
            pool_sema.release()
